//File: Mergesort.java //A Java application to illustrate the use of a merge sort //Additional javadoc documentation is available at: //http://www.cs.colorado.edu/~main/docs/Mergesort.html /******************************************************************************* * The <CODE>Mergesort</CODE> Java application illustrates a merge sort. * * <p> * <dt><b>Java Source Code for this class: </b> * <dd><A HREF="http://www.cs.colorado.edu/~main/applications/Mergesort.java"> * http://www.cs.colorado.edu/~main/applications/Mergesort.java </A> * * @author Michael Main <A HREF="mailto:main@colorado.edu"> (main@colorado.edu) * </A> * * @version Jun 12, 1998 ******************************************************************************/ public class MergeSort { /** * The main method illustrates the use of a merge sort to sort a small * array. The <CODE>String</CODE> arguments (<CODE>args</CODE>) are * not used in this implementation. */ /* * public static void main(String[] args) { final String BLANKS = " "; // A * String of two blanks int i; // Array index * * String[] data = {"Shahein", "Abena", "Ryan", "John"}; // Print the array * before sorting: System.out.println("Here is the entire original array:"); * for (i = 0; i < data.length; i++) System.out.print(data[i] + BLANKS); * System.out.println(); // Sort the numbers, and print the result with two * blanks after each // number. sort(data, 0, data.length ); * System.out.println("I have sorted all the strings."); * System.out.println("The strings are:"); for (i = 0; i < data.length; i++) * System.out.print(data[i] + BLANKS); System.out.println(); } * * /** Sort an array of integers from smallest to largest, using a merge * sort algorithm. * * @param <CODE> data </CODE> the array to be sorted @param <CODE> frst * </CODE> the start index for the portion of the array that will be sorted * @param <CODE> n </CODE> the number of elements to sort <dt> * <b>Precondition: </b> <dd><CODE> data[first] </CODE> through <CODE> * data[first+n-1] </CODE> are valid parts of the array. <dt> * <b>Postcondition: </b> <dd> If <CODE> n </CODE> is zero or negative then * no work is done. Otherwise, the elements of </CODE> data </CODE> have * been rearranged so that <CODE> data[first] <= data[first+1] <= ... * <= data[first+n-1] </CODE> . @exception ArrayIndexOutOfBoundsException * Indicates that <CODE> first+n-1 </CODE> is an index beyond the end of the * array. */ public static void sort(Book[] data, int first, int n, int type) { int n1; // Size of the first half of the array int n2; // Size of the second half of the array if(n > 1) { // Compute sizes of the two halves n1 = n / 2; n2 = n - n1; sort(data, first, n1, type); // Sort data[first] through // data[first+n1-1] sort(data, first + n1, n2, type); // Sort data[first+n1] to the // end // Merge the two sorted halves. merge(data, first, n1, n2, type); } } private static void merge(Book[] data, int first, int n1, int n2, int type) // Precondition: data has at least n1 + n2 components starting at // data[first]. The first // n1 elements (from data[first] to data[first + n1 � 1] are sorted from // smallest // to largest, and the last n2 (from data[first + n1] to data[first + n1 + // n2 - 1]) are also // sorted from smallest to largest. // Postcondition: Starting at data[first], n1 + n2 elements of data // have been rearranged to be sorted from smallest to largest. // Note: An OutOfMemoryError can be thrown if there is insufficient // memory for an array of n1+n2 ints. { Book[] temp = new Book[n1 + n2]; // Allocate the temporary // array int copied = 0; // Number of elements copied from data to temp int copied1 = 0; // Number copied from the first half of data int copied2 = 0; // Number copied from the second half of data int i; // Array index to copy from temp back into data // Merge elements, copying from two halves of data to the temporary // array. if(type == 0) { while((copied1 < n1) && (copied2 < n2)) { Book temp1 = data[first + copied1]; Book temp2 = data[first + n1 + copied2]; boolean before = false, after = false, equal = false; if(temp1.getCatalogNum().compareTo(temp2.getCatalogNum()) > 0) after = true; else if(temp1.getCatalogNum().compareTo(temp2.getCatalogNum()) < 0) before = true; else equal = true; //if (data[first + copied1] < data[first + n1 + copied2]) if(before) temp[copied++] = data[first + (copied1++)]; else temp[copied++] = data[first + n1 + (copied2++)]; } } else if(type == 1) { while((copied1 < n1) && (copied2 < n2)) { boolean before = false, after = false, equal = false; if(data[first + copied1].getAuthor().compareTo( data[first + n1 + copied2].getAuthor()) > 0) after = true; else if(data[first + copied1].getTitle().compareTo( data[first + n1 + copied2].getTitle()) < 0) before = true; else equal = true; //if (data[first + copied1] < data[first + n1 + copied2]) if(before) temp[copied++] = data[first + (copied1++)]; else temp[copied++] = data[first + n1 + (copied2++)]; } } else { while((copied1 < n1) && (copied2 < n2)) { boolean before = false, after = false, equal = false; if(data[first + copied1].getTitle().compareTo( data[first + n1 + copied2].getTitle()) > 0) after = true; else if(data[first + copied1].getTitle().compareTo( data[first + n1 + copied2].getTitle()) < 0) before = true; else equal = true; //if (data[first + copied1] < data[first + n1 + copied2]) if(before) temp[copied++] = data[first + (copied1++)]; else temp[copied++] = data[first + n1 + (copied2++)]; } } // Copy any remaining entries in the left and right subarrays. while(copied1 < n1) temp[copied++] = data[first + (copied1++)]; while(copied2 < n2) temp[copied++] = data[first + n1 + (copied2++)]; // Copy from temp back to the data array. for(i = 0; i < n1 + n2; i++) data[first + i] = temp[i]; } }